package online.dgyj.allinone;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.nle.mylibrary.claimer.connector.ConnectorListener;
import com.nle.mylibrary.databus.DataBusFactory;
import com.nle.mylibrary.device.GenericConnector;
import com.nle.mylibrary.device.listener.ConnectResultListener;

import java.util.concurrent.TimeUnit;

@SuppressLint("SetTextI18n")
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Handler handler;
    private GenericConnector genericConnector;
    private String ip;
    private int port, address;
    private final Thread getSensorThread = getSensor();

    private TextView sensor1Text, sensor2Text, sensor3Text, sensor4Text, sensor5Text, sensor6Text;
    private TextView sensor1Value, sensor2Value, sensor3Value, sensor4Value, sensor5Value, sensor6Value;
    private EditText IPEdit, PortEdit, AddressEdit;
    private Switch RTUSwitch;
    private Button LinkBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

        bind();
    }

    /**
     * 初始化视图
     * 此方法主要适配通用UI,正常不推荐
     */
    private void InitView() {
        sensor1Text.setText("温度");
        sensor2Text.setText("湿度");
        sensor3Text.setText("人体");
        sensor4Text.setText("PM2.5");
        sensor5Text.setText("空气质量");
        sensor6Text.setText("气压");

        AddressEdit.setEnabled(false);
    }

    /**
     * 实例化控件
     */
    private void bind() {

        handler = new Handler(Looper.getMainLooper());

        sensor1Text = findViewById(R.id.sensor1Text);
        sensor2Text = findViewById(R.id.sensor2Text);
        sensor3Text = findViewById(R.id.sensor3Text);
        sensor4Text = findViewById(R.id.sensor4Text);
        sensor5Text = findViewById(R.id.sensor5Text);
        sensor6Text = findViewById(R.id.sensor6Text);

        sensor1Value = findViewById(R.id.sensor1Value);
        sensor2Value = findViewById(R.id.sensor2Value);
        sensor3Value = findViewById(R.id.sensor3Value);
        sensor4Value = findViewById(R.id.sensor4Value);
        sensor5Value = findViewById(R.id.sensor5Value);
        sensor6Value = findViewById(R.id.sensor6Value);

        IPEdit = findViewById(R.id.IPEdit);
        PortEdit = findViewById(R.id.PortEdit);
        AddressEdit = findViewById(R.id.AddressEdit);

        RTUSwitch = findViewById(R.id.RTUSwitch);

        LinkBtn = findViewById(R.id.LinkBtn);

        InitView();

        LinkBtn.setOnClickListener(this);   // 事件处理

        RTUSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { // 事件处理
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    IPEdit.setHint("SerialName");
                    PortEdit.setHint("Baud");
                    IPEdit.setText("");
                    PortEdit.setText("");
                } else {
                    IPEdit.setHint("IP");
                    PortEdit.setHint("Port");
                    IPEdit.setText("");
                    PortEdit.setText("");
                }
            }
        });
    }

    /**
     * 获取多合一设备地址
     */
    private void getDeviceAddress() {
        try {
            genericConnector.sendAllInOneGetAddress(new ConnectorListener() {
                @Override
                public void onSuccess(boolean b) {
                    Log.i("Device Address", String.valueOf(address));
                    address = genericConnector.getAllInOneGetAddress();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            AddressEdit.setText(String.valueOf(address));
                        }
                    });
                    try {
                        TimeUnit.SECONDS.sleep(1);
                        getSensorThread.start();    // 开始获取全部数据
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                }

                @Override
                public void onFail(Exception e) {

                }
            });
        } catch (Exception e) {
            Log.e("Get Device Address", e.toString());
        }
    }

    private int tag = 0;    // 标志 用于保持多线程中单线程的顺序执行

    /**
     * 获取传感器数据
     *
     * @return 线程
     */
    private Thread getSensor() {
        return new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        if (tag == 0)
                            getTempHum();   // 读取温度
                        // 等待获取完成
                        while (tag == 0) {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                        if (tag == 1)
                            getBody();
                        while (tag == 1) {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                        if (tag == 2)
                            getPressure();
                        while (tag == 2) {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                        if (tag == 3)
                            getPM25();
                        while (tag == 3) {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                        if (tag == 4)
                            getAirQuality();
                        while (tag == 4) {
                            TimeUnit.MILLISECONDS.sleep(100);
                        }
                        TimeUnit.SECONDS.sleep(1);
                        tag = 0;
                    } catch (InterruptedException e) {
                        break;
                    }
                }
            }
        });
    }

    /**
     * 获取温湿度
     */
    private void getTempHum() {
        try {
            genericConnector.sendAllInOneTempHum(address, new ConnectorListener() {
                @Override
                public void onSuccess(boolean b) {
                    int temp, hum;
                    temp = genericConnector.getAllInOneTemp();
                    hum = genericConnector.getAllInOneHum();

                    Log.i("TempHum", String.format("temp:%d hum:%d", temp, hum));

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (temp >= 1 && temp <= 100) {
                                sensor1Value.setText(String.valueOf(temp));
                            }
                            if (hum >= 1 && hum <= 100) {
                                sensor2Value.setText(String.valueOf(hum));
                            }
                        }
                    });

                    tag = 1;
                }

                @Override
                public void onFail(Exception e) {

                }
            });
        } catch (Exception e) {
            Log.e("Get TempHum", e.toString());
        }
    }

    /**
     * 获取人体
     */
    private void getBody() {
        try {
            genericConnector.sendAllInOneBody(address, new ConnectorListener() {
                @Override
                public void onSuccess(boolean b) {
                    int body = genericConnector.getAllInOneBody();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (body == 0) {
                                sensor3Value.setText("无人");
                            } else if (body == 1) {
                                sensor3Value.setText("有人");
                            }
                        }
                    });
                    tag = 2;
                }

                @Override
                public void onFail(Exception e) {

                }
            });
        } catch (Exception e) {
            Log.e("Get Body", e.toString());
        }
    }

    /**
     * 获取气压
     * 疑似方法失效
     */
    private void getPressure() {
        try {
            genericConnector.sendAllInOnePressure(address, new ConnectorListener() {
                @Override
                public void onSuccess(boolean b) {
                    int pressure = genericConnector.getAllInOnePressure();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            sensor6Value.setText(String.valueOf(pressure));
                        }
                    });
                    tag = 3;
                }

                @Override
                public void onFail(Exception e) {

                }
            });
        } catch (Exception e) {
            Log.e("Get Pressure", e.toString());
        }
    }

    /**
     * 获取PM2.5
     * 疑似方法失效
     */
    private void getPM25() {
        try {
            genericConnector.sendAllInOnePM25(address, new ConnectorListener() {
                @Override
                public void onSuccess(boolean b) {
                    int pm25 = genericConnector.getAllInOnePm25();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            sensor4Value.setText(String.valueOf(pm25));
                        }
                    });
                    tag = 4;
                }

                @Override
                public void onFail(Exception e) {

                }
            });
        } catch (Exception e) {
            Log.e("Get PM2.5", e.toString());
        }
    }

    /**
     * 获取空气质量
     */
    private void getAirQuality() {
        try {
            genericConnector.sendAllInOneAirQuality(address, new ConnectorListener() {
                @Override
                public void onSuccess(boolean b) {
                    int AirQuality = genericConnector.getAllInOneAirQuality();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            sensor5Value.setText(String.valueOf(AirQuality));
                        }
                    });
                    tag = 5;
                }

                @Override
                public void onFail(Exception e) {

                }
            });
        } catch (Exception e) {
            Log.e("Get PM2.5", e.toString());
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.LinkBtn) {
            if (genericConnector == null) {
                ip = IPEdit.getText().toString();
                port = Integer.parseInt(PortEdit.getText().toString());
                if (RTUSwitch.isChecked()) {
                    Log.i("Start", "Start");
                    genericConnector = new GenericConnector(DataBusFactory.newSerialDataBus(Integer.parseInt(ip), port), new ConnectResultListener() {
                        @Override
                        public void onConnectResult(boolean b) {
                            if (b) {
                                Log.i("Rtu Status", "Link OK");
                                getDeviceAddress();
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        IPEdit.setEnabled(false);
                                        RTUSwitch.setEnabled(false);
                                        PortEdit.setEnabled(false);
                                        LinkBtn.setText("DISC");
                                        Toast.makeText(getApplication(), "连接成功", Toast.LENGTH_SHORT).show();
                                    }
                                });

                            } else {
                                Log.e("Rtu Status", "Link Error");
                                genericConnector = null;// 销毁
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(getApplicationContext(), "连接失败", Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }
                        }
                    });
                } else {
                    genericConnector = new GenericConnector(DataBusFactory.newSocketDataBus(ip, port), new ConnectResultListener() {
                        @Override
                        public void onConnectResult(boolean b) {
                            if (b) {
                                Log.i("tcp Status", "Link OK");
                                getDeviceAddress();
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        IPEdit.setEnabled(false);
                                        PortEdit.setEnabled(false);
                                        RTUSwitch.setEnabled(false);
                                        LinkBtn.setText("DISC");
                                        Toast.makeText(getApplication(), "连接成功", Toast.LENGTH_SHORT).show();
                                    }
                                });
                            } else {
                                Log.e("tcp Status", "Link Error");
                                genericConnector = null;// 销毁
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(getApplicationContext(), "连接失败", Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }
                        }
                    });
                }
            } else {
                getSensorThread.interrupt();

                IPEdit.setEnabled(true);
                RTUSwitch.setEnabled(true);
                PortEdit.setEnabled(true);

                LinkBtn.setText("Link");

                Toast.makeText(getApplication(), "断开连接", Toast.LENGTH_SHORT).show();

                // 销毁
                genericConnector.stopConnect();
                genericConnector = null;
            }
        }
    }
}